package org.naxx.security.xgen.parts;

import java.util.Date;
import java.util.List;

import org.naxx.security.expression.Node;
import org.naxx.security.model.match.Match;
import org.naxx.security.model.match.MatchContainer;
import org.naxx.security.xgen.XExpressionGenerator;
import org.naxx.security.xgen.util.JavaNameGenerator;
import org.naxx.security.xgen.util.XWriter;

public final class XMatchContainerGenerator extends XAbstractGenerator {
	
	private final JavaNameGenerator javaNameGenerator = new JavaNameGenerator();

	public void generateMatchCondition(XWriter writer, MatchContainer matchContainer, 
			String className) throws Exception {
		
		this.writeHeader(writer, className);
		List<Match> matches = matchContainer.getMatches();
		for(Match match : matches) {
			this.createAnonymClass(writer, match);
		}
		this.writeFooter(writer);
	}
	
	void createAnonymClass(XWriter writer, Match match) throws Exception {
		writer.write("addXMatch(new XAbstractMatch() {protected Boolean exec() {");
		XExpressionGenerator x = new XExpressionGenerator();
		String lastVariableName = x.generate(writer, match.asTree());
//		String lastVariableName = this.writeExpression(writer, match.asTree());
		writer.write("return " + lastVariableName + ";");
		writer.write("}" + "}");
		writer.write(");");
	}
	
	String writeExpression(XWriter writer, Node root) throws Exception {
		XExpressionGenerator x = new XExpressionGenerator();
		String lastVariableName = x.generate(writer, root);
		return lastVariableName;
	}
	
	// procees from here
	private String getExpressionString(Match match) {
		String xriptlet = match.getFunctionType().getXriptlet();
		Object value = match.getValueHolder().getValue();
		String firstVar = this.javaNameGenerator.getNextUniqueVariableName();
		xriptlet = xriptlet.replace("${arg[0]}", value.toString());
		xriptlet = xriptlet.replace("${arg[1]}", value.toString()); // add here pulling from request context
		final String variableName = this.javaNameGenerator.getNextUniqueVariableName();
		xriptlet = xriptlet.replace("${resultVarName}", variableName);
		
		return xriptlet + "return " + variableName +";";
	}
	
	void writeHeader(XWriter writer, String className) throws Exception {
		writer.write("// Auto generated on " + new Date());
		writer.write("package org.naxx.security.generated;");
		writer.write("");
		writer.write("import org.naxx.security.*;"); // FIXME
		writer.write("import org.naxx.security.model.request.Request;");
		writer.write("import java.util.List;");
		writer.write("import org.naxx.security.naxxlet.model.*;");
		writer.write("");
		writer.write("public final class " + className + " extends "
					+ " XAbstractMatchContainer {");
		writer.write("");
		writer.write("@SuppressWarnings(\"unchecked\")");
		writer.write("public " + className + "() {");
	}
	
	void writeFooter(XWriter writer) throws Exception {
		writer.write("}");
		writer.write("");
		writer.write("}" + " // end of generated class");
	}
}
